﻿using System;
using System.Windows.Forms;
using AmiEmuLib.Native;

namespace AmiEmuLib.Host
{
    /// <summary>
    /// This interface should be implemented by main window and used in HostEnvironment
    /// initialization.
    /// </summary>
    public class HostWindow : Form
    {
        /// <summary>
        /// Device changed.
        /// </summary>
        public event MessageEvent Input;

        /// <summary>
        /// Input event.
        /// </summary>
        /// <param name="a_message"></param>
        /// <returns></returns>
        public event MessageEvent DeviceChanged;

        /// <summary>
        /// Invoke.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="a_delegate"></param>
        /// <returns></returns>
        public T Invoke<T>(Func<T> a_delegate)
        {
            if (InvokeRequired)
            {
                try
                {
                    return (T)base.Invoke(a_delegate);
                }
                catch (ObjectDisposedException)
                {
                    return default(T);
                }
            }
            else if (IsHandleCreated)
                return a_delegate();
            else
                return default(T);
        }

        /// <summary>
        /// Invoke.
        /// </summary>
        /// <param name="a_delegate"></param>
        public void Invoke(Action a_delegate)
        {
            if (InvokeRequired)
                BeginInvoke(a_delegate);
            else if (IsHandleCreated)
                a_delegate();
        }

        protected override void WndProc(ref Message a_msg)
        {
            if (a_msg.Msg == (int)NativeConsts.WM_INPUT)
            {
                if (Input != null)
                    Input(ref a_msg);
            }
            else if (a_msg.Msg == (int)NativeConsts.WM_DEVICECHANGE)
            {
                if (DeviceChanged != null)
                    DeviceChanged(ref a_msg);
            }

            base.WndProc(ref a_msg);
        }
    }
}